package commands;

import io.XMLInteractor;

import java.util.List;

import core.GameManager;
import core.UserManager;
import user.User;
import util.Pair;
import messages.GiveUpMessage;
import messages.MatchEndedMessage;
import messages.Message;
import event.MatchEndedEventArgs;
import game.Match;
import game.MatchStatistics;
import game.Player;


/**
 * The GiveUp command.
 * 
 * This GiveUp will handle Quit messages.
 */
public class GiveUpCommand extends Command {

	
	public GiveUpCommand(Message message, User user) {
		super(message, user);
	}
	
	
	@Override
	public void execute() {
		UserManager userManager = this.controller.getUserManager();
		GameManager gameManager = controller.getGameManager();
		GiveUpMessage message = (GiveUpMessage) this.message;
		Player player = this.user.getPlayer();

		synchronized (userManager) {
			synchronized (gameManager) {
				Match match = gameManager.getMatch(message.getMatchId());
	
				if (match == null) {
					// There is no such match! Ignore.
					return;
				} else if (!match.getPlayers().contains(player)) {
					// User is trying to cancel a match he doesn't belong to?!
					// TODO
					return;
				}
	
				match.giveUp(player);
	
				// Update rankings.
				List<Pair<Player, Integer>> score = match.getRankingPoints();
				for (Pair<Player, Integer> pair : score) {
					Player p = pair.getFirst();
					synchronized(p) {
						p.incRanking(pair.getSecond());
					}
				}
				
				userManager.saveKnownUsers();
				
				MatchStatistics matchStatistics = new MatchStatistics(match);
				XMLInteractor.saveMatch(matchStatistics);
	
				MatchEndedMessage gameEndedMessage = 
					new MatchEndedMessage(match.getPlayers(), matchStatistics);
	
				gameManager.removeMatch(match.getId());
	
				// Sends the message to everyone.
				this.controller.fireMatchEndedEvent(new MatchEndedEventArgs(gameEndedMessage));
			}
		}
	}
}
